package com.common.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import com.common.exception.ParseDatesException;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

/**
 * map映射成java类

 */
public class BeanUtils {

    public static <T> T getBean(Class<T> clazz, Map map) throws InvocationTargetException, IllegalAccessException, InstantiationException {
        if (clazz != null && map != null) {
            Method[] methods = clazz.getMethods();
            T t = clazz.newInstance();
            for (Object key : map.keySet()) {
                for (Method method : methods) {
                    if (method.getName().startsWith("set")) {
                        String fieldName = method.getName().substring(3);
                        fieldName = fieldName.toLowerCase();
                        if (key.equals(fieldName)) {
                            String typeName= map.get(key).getClass().getTypeName();
                            if (typeName.equals("String")) {
                                method.invoke(t, (String)map.get(key));
                            }else if(typeName.equals("Long")){

                            }
                        }
                    }
                }
            }
            return t;
        }
        return null;
    }
    
    /**
     * 
     * @param dest
     * @param orig
     */
    public static void copyProperties(Object target, Object source) 
    		throws ParseDatesException {
    	if (target == null || source == null) {  
            return;  
        }  
    	
		try {
			org.springframework.beans.BeanUtils.copyProperties(source, target);
			//BeanUtils.copyProperties(dest, orig);
		} catch (Exception e) {
			throw new ParseDatesException("copyProperties", e.getCause());
		}
    }
    
    /**
     * 
     * @param dest
     * @param orig
     */
    public static void copyProperties(Object dest, Object orig,String... ignore) 
    		throws ParseDatesException {
    	if (dest == null || orig == null) {  
            return;  
        }  
    	
		try {
			org.springframework.beans.BeanUtils.copyProperties(orig, dest,ignore);
			//BeanUtils.copyProperties(dest, orig);
		} catch (Exception e) {
			throw new ParseDatesException("copyProperties", e.getCause());
		}
    }
    
    /**
     * 得到bean为空的属性
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames (Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    // Map --> Bean 2: 利用org.apache.commons.beanutils 工具类实现 Map --> Bean
    public static void transMap2Bean2(Map<String, Object> map, Object obj) {
        if (map == null || obj == null) {
            return;
        }
        try {
            org.apache.commons.beanutils.BeanUtils.populate(obj, map);
        } catch (Exception e) {
            System.out.println("transMap2Bean2 Error " + e);
        }
    }

    // Map --> Bean 1: 利用Introspector,PropertyDescriptor实现 Map --> Bean
    public static void transMap2Bean(Map<String, Object> map, Object obj) {

        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();

            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();

                if (map.containsKey(key)) {
                    Object value = map.get(key);
                    // 得到property对应的setter方法
                    Method setter = property.getWriteMethod();
                    setter.invoke(obj, value);
                }

            }

        } catch (Exception e) {
            System.out.println("transMap2Bean Error " + e);
        }

        return;

    }

    // Bean --> Map 1: 利用Introspector和PropertyDescriptor 将Bean --> Map
    public static Map<String, Object> transBean2Map(Object obj) {

        if(obj == null){
            return null;
        }
        Map<String, Object> map = new HashMap<String, Object>();
        try {
            BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor property : propertyDescriptors) {
                String key = property.getName();

                // 过滤class属性
                if (!key.equals("class")) {
                    // 得到property对应的getter方法
                    Method getter = property.getReadMethod();
                    Object value = getter.invoke(obj);

                    map.put(key, value);
                }

            }
        } catch (Exception e) {
            System.out.println("transBean2Map Error " + e);
        }

        return map;

    }
    
//    public static void main(String[] args) throws IllegalAccessException, InstantiationException, InvocationTargetException {
//       /* Map<String, String> map = new HashMap<>();
//        map.put("kid","1");
//        Test test = getBean(Test.class, map);
//        System.out.println(test.getKid());*/
//
//       String s = "15327533357";
//        String s1 = s.substring(s.length() - 9, s.length());
//        System.out.println(s1);
//    }
}
